home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / c / hce.lha / HCE / LibSource / clib / Misc / src / time.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-02  |  6.5 KB  |  242 lines

  1. /*
  2.  * DATE/TIME FUNCTIONS:
  3.  *
  4.  *    To use the functions in this section, you must include "TIME.H"
  5.  *    in your source file.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <time.h>
  10. #include    <exec/types.h>
  11. #include    <exec/lists.h>
  12. #include    <devices/timer.h>
  13.  
  14. static struct tm    the_time;
  15.  
  16. static char        timebuf[26] =
  17.             "Day Mon dd hh:mm:ss yyyy\n";
  18. static char        *day[] =
  19.             {"", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  20. static char        *month[] =
  21.             {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  22.             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  23.  
  24. long julian_date(time)
  25.     register struct tm *time;
  26. /*
  27.  *    Number of days since the base date of the Julian calendar.
  28.  */
  29.     {
  30.     register long c, y, m, d;
  31.  
  32.     y = time->tm_year + 1900;    /* year - 1900 */
  33.     m = time->tm_mon;        /* month, 1..12 */
  34.     d = time->tm_mday;        /* day, 1..31 */
  35.     if(m > 2)
  36.         m -= 3L;
  37.     else
  38.         {
  39.         m += 9L;
  40.         y -= 1L;
  41.         }
  42.     c = y / 100L;
  43.     y %= 100L;
  44.     return(    ((146097L * c) >> 2) +
  45.         ((1461L * y) >> 2) +
  46.         (((153L * m) + 2) / 5) +
  47.         d +
  48.         1721119L );
  49.     }
  50.  
  51. static char *notimer = "Warning: can't open timer device\n";
  52. #define    MSGSIZE 33L
  53. typedef struct MsgPort    MSG;
  54.  
  55. time_t time(rawtime)
  56.     register long *rawtime;
  57. /*
  58.  *    Get the current system clock date/time value.  Under many systems,
  59.  *    this function returns the number of seconds since 00:00:00 GMT on
  60.  *    Jan 1, 1970.  This implementation returns an encoded date/time
  61.  *    value instead.  Therefore any programs which depend on this value
  62.  *    being a number of seconds will not work properly.  However, other
  63.  *    functions in this section which make use of the raw time value
  64.  *    returned by time() are implemented to be compatible with this
  65.  *    encoding, and will work properly.  In addition to returning the
  66.  *    raw time value, if the <rawtime> pointer in not NULL, the value
  67.  *    is stored in the long <rawtime> points to.
  68.  *
  69.  *    Note: Amigatime is # seconds since midnight, Jan 1st, 1978.
  70.  */
  71. {
  72.     extern MSG *CreatePort();
  73.     extern long Output(), OpenDevice();
  74.     register time_t t;
  75.     struct timerequest tr;
  76.  
  77.  
  78.     if (OpenDevice( TIMERNAME, UNIT_VBLANK, &tr, 0L) ){
  79.         Write( Output(), notimer, MSGSIZE );
  80.         return 0;
  81.     }
  82.  
  83.     tr.tr_node.io_Message.mn_ReplyPort = CreatePort(0L, 0L);
  84.     tr.tr_node.io_Command = TR_GETSYSTIME;
  85.     DoIO(&tr);
  86.     t = tr.tr_time.tv_secs + (tr.tr_time.tv_micro + 500000) / 1000000;
  87.     CloseDevice(&tr);
  88.     DeletePort(tr.tr_node.io_Message.mn_ReplyPort);
  89.  
  90.     if(rawtime)
  91.         *rawtime = t;
  92.     return(t);
  93. }
  94.  
  95. struct tm *gmtime()
  96. /*
  97.  *    Can't determine Greenwich Mean Time, so return NULL
  98.  *    as specified by ANSI standard.
  99.  */
  100.     {
  101.     return(NULL);
  102.     }
  103.  
  104. #define SECPERDAY    (24L*60L*60L)
  105. #define SECPERHR    (60L*60L)
  106. #define SECPERMIN    (60L)
  107. struct tm *localtime(rawtime)
  108.     time_t *rawtime;
  109. /*
  110.  *    Convert <rawtime> to fill time structure fields.  A pointer to an
  111.  *    internal structure is returned.  Refer to "TIME.H" for the values
  112.  *    of the various structure fields.
  113.  *
  114.  *    This routine is adapted from Tomas Rokicki's exellent example,
  115.  *    "ShowDate.c" - Jeff.
  116.  */
  117.     {
  118.     register time_t n, y, m;
  119.     register time_t time;
  120.     register struct tm *t;
  121.  
  122.     time = *rawtime;
  123.     t = &the_time;
  124.  
  125. /*
  126.  *   Set $n$ to the number of days since Amiga day -671, which is
  127.  *   March 1, 1976.  It's easier to figure years starting in March,
  128.  *   since then the lengths of the months are 31, 30, 31, 30, 31,
  129.  *   31, 30, 31, 30, 31, 31, 28.  This is almost linear.
  130.  */
  131.        n = time / SECPERDAY + 671;
  132. /*
  133.  *   The easiest is the weekday.  This is simply the number of days
  134.  *   modulo 7, corrected for the start date.  March 1, 1976 was a
  135.  *   Monday, so we add 1 to get back to a Sunday, take the modulo,
  136.  *   and add one to start our days on Sunday.
  137.  */
  138.     t->tm_wday = (n + 1) % 7 + 1 ;
  139. /*
  140.  *   There are exactly 1461 days every four years, until 2100, which
  141.  *   is the first year divisible by 4 that is not a leap year AA
  142.  *   (After Amiga.)  This gives the years lengths of 365 (1976),
  143.  *   365 (1977), 365 (1978), and 366 (1979).  Note that this is
  144.  *   correct because we start our years in March, so 1979 is the
  145.  *   leap year.
  146.  */
  147.     y = (4 * n + 3) / 1461 ;
  148. /*
  149.  *   We now subtract off the years (see them melt off her face.)
  150.  *   We use a long constant for 16-bit systems.  Again we use the
  151.  *   fact that the leap year is the fourth year, not the first.
  152.  */
  153.     n -= 1461L * y / 4 ;
  154.     t->tm_yday = n + 60;
  155. /*
  156.  *   Now we can adjust the year to the proper value by adding
  157.  *   1976.
  158.  */
  159.     y += 76 ;
  160. /*
  161.  *   We calculate the month.  Since we start in March, the length
  162.  *   of the months are always 30 or 31, except for the last month,
  163.  *   which is shorter.  This is fortunate, as it allows us to use
  164.  *   a simple mathematical formula for the month.  The lengths of
  165.  *   the months are (31, 30, 31, 30, 31), repeated three times and
  166.  *   the end lopped off.  So, our slope is 153/5.  An intercept of
  167.  *   2 gives us the 31 and 30 lengths.
  168.  */
  169.     m = (5 * n + 2) / 153 ;
  170. /*
  171.  *   And now we subtract off the months.  Oh, yeah, we add 1 because
  172.  *   the first day of each month is the first, not the zeroth.
  173.  */
  174.        t->tm_mday = n - (153 * m + 2) / 5 + 1 ;
  175. /*
  176.  *   Now we convert from March-based years back to January-based
  177.  *   years.  We add 2 for this shift, and another 1 to give us
  178.  *   January = 1 through December = 12.
  179.  */
  180.     m += 3 ;
  181. /*
  182.  *   And, if we've gone over 12, we increment the year.
  183.  */
  184.     if (m > 12) {
  185.         y++ ;
  186.         m -= 12 ;
  187.     }
  188.  
  189.     t->tm_year = y;
  190.     t->tm_mon  = m;
  191.  
  192. /*
  193.  * Guess I'll have to figure out the rest myself.  Thanks, Tomas.
  194.  */
  195.  
  196.     time %= SECPERDAY;    /* # seconds since midnight today */
  197.     n = time / SECPERHR;    /* hours since midnight */    
  198.     t->tm_hour = n;
  199.  
  200.     time -= n * SECPERHR;    
  201.     n = time / SECPERMIN;
  202.     t->tm_min = n;
  203.  
  204.     time -= n * SECPERMIN;
  205.     t->tm_sec = time;
  206.  
  207.     t->tm_isdst = (-1);
  208.     return(t);
  209.     }
  210.  
  211. char *asctime(time)
  212.     register struct tm *time;
  213. /*
  214.  *    Convert <time> structure value to a string.  The same format, and
  215.  *    the same internal buffer, as for ctime() is used for this function.
  216.  */
  217.     {
  218.     sprintf(timebuf, "%.3s %.3s%3d %02d:%02d:%02d %04d\n",
  219.         day[time->tm_wday], month[time->tm_mon], time->tm_mday,
  220.         time->tm_hour, time->tm_min, time->tm_sec, 1900+time->tm_year);
  221.     return(timebuf);
  222.     }
  223.  
  224. char *ctime(rawtime)
  225.     time_t *rawtime;
  226. /*
  227.  *    Convert <rawtime> to a string.  A 26 character fixed field string
  228.  *    is created from the raw time value.  The following is an example
  229.  *    of what this string might look like:
  230.  *        "Wed Jul 08 18:43:07 1987\n\0"
  231.  *    A 24-hour clock is used, and due to a limitation in the ST system
  232.  *    clock value, only a resolution of 2 seconds is possible.  A pointer
  233.  *    to the formatted string, which is held in an internal buffer, is
  234.  *    returned.
  235.  */
  236.     {
  237.     char *asctime();
  238.     struct tm *localtime();
  239.  
  240.     return(asctime(localtime(rawtime)));
  241.     }
  242.